package cn.test.blockingqueue.delay;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

@Slf4j
public class DelayQueueTest2 {
    static class CacheItem implements Delayed {

        private String key;

        /**
         * 过期时间(单位秒)
         */
        private long exprieTime;

        private long currentTime;

        public CacheItem(String key, long exprieTime) {
            this.key = key;
            this.exprieTime = exprieTime;
            this.currentTime = System.currentTimeMillis();
        }

        @Override
        public long getDelay(TimeUnit unit) {
            // 计算剩余的过期时间
            // 大于 0 说明未过期
            return exprieTime - TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - currentTime);
        }

        @Override
        public int compareTo(Delayed o) {
            // 过期时间长的放置在队列尾部
            if (this.getDelay(TimeUnit.MICROSECONDS) > o.getDelay(TimeUnit.MICROSECONDS)) {
                return 1;
            }
            // 过期时间短的放置在队列头
            if (this.getDelay(TimeUnit.MICROSECONDS) < o.getDelay(TimeUnit.MICROSECONDS)) {
                return -1;
            }

            return 0;
        }

        @Override
        public String toString() {
            return "CacheItem{" +
                    "key='" + key + '\'' +
                    ", exprieTime=" + exprieTime +
                    ", currentTime=" + currentTime +
                    '}';
        }

        public String getKey() {
            return key;
        }
    }

    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<CacheItem> queue = new DelayQueue<>();

        // 添加缓存元素
        CacheItem cache1 = new CacheItem("a", 5);
        CacheItem cache2 = new CacheItem("b", 4);
        CacheItem cache3 = new CacheItem("c", 3);

        queue.put(cache1);
        queue.put(cache2);
        queue.put(cache3);

        log.debug("put完毕");
        log.debug(queue.take().toString());
        log.debug("睡眠5秒");
        Thread.sleep(5000);
        log.debug(queue.take().toString());
        log.debug(queue.take().toString());
    }
}
